{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 用户社交数据（user_friends.csv）处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 导入工具包\n",
    "\n",
    "import pandas as pd\n",
    "\n",
    "import numpy as np\n",
    "import scipy.sparse as ss\n",
    "import scipy.io as sio\n",
    "\n",
    "#保存数据\n",
    "import pickle\n",
    "\n",
    "from sklearn.preprocessing import normalize"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "总的用户数目超过训练集和测试集中的用户，\n",
    "为节省处理时间和内存，先去处理train和test，得到竞赛需要用到的活动和用户\n",
    "然后对在训练集和测试集中出现过的事件和用户建立新的ID索引\n",
    "先运行user_event.ipynb,\n",
    "得到事件列表文件：PE_userIndex.pkl"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Number of users in train & test:3391\n"
     ]
    }
   ],
   "source": [
    "# 读取训练集和测试集中出现过的用户列表\n",
    "userIndex = pickle.load(open('PE_userIndex.pkl', 'rb'))\n",
    "n_users = len(userIndex)\n",
    "\n",
    "print(\"Number of users in train & test:%d\" % n_users)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 读取之前用户-活动分数矩阵，将朋友参加活动的影响扩展到用户\n",
    "\n",
    "userEventScores = sio.mmread(\"PE_userEventScores\")\n",
    "\n",
    "#后续用于将用户朋友参加的活动影响到用户\n",
    "eventsForUser = pickle.load(open(\"PE_eventsForUser.pkl\", 'rb'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<function BufferedReader.close>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"\"\"\n",
    "  找出某用户的那些朋友\n",
    "  1)如果你有更多的朋友，可能你性格外向，更容易参加各种活动\n",
    "  2)如果你朋友会参加某个活动，可能你也会跟随去参加一下\n",
    "\"\"\"\n",
    "# 用户有多少个朋友\n",
    "numFriends = np.zeros((n_users))\n",
    "userFriends = ss.dok_matrix((n_users, n_users))\n",
    "\n",
    "# 读取数据\n",
    "fin = open('/Users/cuiyue/Desktop/AI/第四周/作业/要求/71-57-1-1519640547/user_friends.csv', 'rb')\n",
    "\n",
    "#字段：user：用户ID, friends：以空格隔开的用户好友ID列表\n",
    "fin.readline()                # 丢掉标题行\n",
    "\n",
    "for line in fin:\n",
    "    cols = line.decode('utf-8').strip().split(',')\n",
    "    user = str(cols[0]) # 用户ID\n",
    "    if user in userIndex: # 若用户出现在训练集和测试集中\n",
    "        friends = cols[1].split()  #friends\n",
    "        i = userIndex[user] #用户的索引\n",
    "        numFriends[i] = len(friends)\n",
    "        for friend in friends:  #该用户的每个朋友\n",
    "            str_friend = str(friend) #好友ID字符串格式化\n",
    "            if str_friend in userIndex: #如果朋友也在训练集或测试集中存在\n",
    "                j = userIndex[str_friend] #这名好友的索引\n",
    "                \n",
    "                # 返回这名好友对所有活动的打分分值的向量（interested or not interested） \n",
    "                eventsForUser = userEventScores.getrow(j).todense()\n",
    "                # 计算score平均值，即这名好友对所有活动打分的和除以所有活动的总数，实际就是他参加活动的频率\n",
    "                score = eventsForUser.sum() / np.shape(eventsForUser)[1]\n",
    "                # 把这个好友的score作为一个影响因子施加给这名好友所属的用户\n",
    "                userFriends[i, j] += score\n",
    "                userFriends[j, i] += score \n",
    "fin.close                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 得到用户的朋友数目并对其归一化\n",
    "sumNumFriends = numFriends.sum(axis=0)\n",
    "numFriends = numFriends / sumNumFriends\n",
    "# 将处理后的用户朋友数保存\n",
    "sio.mmwrite(\"UF_numFriends\", np.matrix(numFriends))\n",
    "\n",
    "userFriends = normalize(userFriends, norm=\"l2\", copy=False)\n",
    "sio.mmwrite(\"UF_userFriends\", userFriends)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
